package com.calculator.pmzvfk;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import java.util.*;

public class FastCalculationActivity extends AppCompatActivity {
    private TextView tvQuestion, tvResult, tvTimer;
    private String currentQuestion;
    private double correctAnswer;
    private int secondsElapsed;
    private Handler timerHandler;
    private Runnable timerRunnable;
    private int score;
    private TextView tvScore;
    private Button[] answerButtons = new Button[4];
    private int correctAnswerIndex;
    private Button btnConfirm;
    private String correctAnswerText;
    private int questionCount = 0;
    private TextView tvProgress;
    private static final int TOTAL_QUESTIONS = 2;
    private Button btnViewLeaderboard;
    private long startTime;
    private Button btnStartGame;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fast_calculation);

        tvQuestion = findViewById(R.id.tvQuestion);
        tvResult = findViewById(R.id.tvResult);
        tvTimer = findViewById(R.id.tvTimer);
        answerButtons[0] = findViewById(R.id.btnOption1);
        answerButtons[1] = findViewById(R.id.btnOption2);
        answerButtons[2] = findViewById(R.id.btnOption3);
        answerButtons[3] = findViewById(R.id.btnOption4);
        tvProgress = findViewById(R.id.tvProgress);
        timerHandler = new Handler();
        timerRunnable = new Runnable() {
            @Override
            public void run() {
                long millis = System.currentTimeMillis() - startTime;
                tvTimer.setText(formatTime(millis));
                timerHandler.postDelayed(this, 100);
            }
        };

        for (Button btn : answerButtons) {
            btn.setOnClickListener(v -> checkAnswer((Button) v));
            btn.setEnabled(false);
        }
        showStartDialog();

        tvScore = findViewById(R.id.tvScore);
        score = 0;
        updateScore(0);


        btnConfirm = findViewById(R.id.btnConfirm);
        btnConfirm.setOnClickListener(v -> {
            btnConfirm.setVisibility(View.GONE);
            generateNewQuestion();
        });

        btnViewLeaderboard = findViewById(R.id.btnViewLeaderboard);
        btnViewLeaderboard.setOnClickListener(v -> showLeaderboard(false));

        btnStartGame = findViewById(R.id.btnStartGame);
        btnStartGame.setOnClickListener(v -> startGame());
    }

    @SuppressLint("SetTextI18n")
    private void startGame() {
        startCountdown();
        btnStartGame.setText("Restart Game");
    }

    private void showStartDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Welcome to the Fast Calculation Game");
        builder.setMessage("Fast Calculation Game Rules:\n" +
                "\n"+
                "Target:\n" +
                "Solve math problems quickly and accumulate as many points as possible.\n" +
                "\n"+
                "Start the game:\n" +
                "Click on the \"Start Game\" button and there will be a short countdown before the game starts.\n" +
                "\n"+
                "Gameplay:\n" +
                "Each round consists of 20 math problems.\n" +
                "Each problem is a basic arithmetic problem (addition, subtraction, multiplication, division).\n" +
                "Each question will be presented with four options, only one of which is correct.\n" +
                "Choose the answer you think is correct. Once selected, the answer cannot be changed.\n" +
                "Points will be awarded for correct answers, and additional points will be awarded for quick answers.\n" +
                "\n"+
                "Scoring:\n" +
                "Each question is scored on a base score of 10.\n" +
                "If you answer correctly within 10 seconds, you will receive an additional 5 points.\n" +
                "No points will be awarded for answering incorrectly.\n" +
                "\n"+
                "Time:\n" +
                "The game keeps track of the total time it takes you to complete 20 questions.\n" +
                "\n"+
                "Check out the leaderboard:\n" +
                "Once you've finished the game, you can see how much you scored and how long you spent in the game.\n" +
                "You can view your historical results and time by clicking on the \"View Leaderboard\" button.\n" +
                "\n"+
                "Resume:\n" +
                "Once you have completed a round of the game, you can select \"Restart the game\" to try again.\n" +
                "\n"+
                "Notes:\n" +
                "It cannot be paused during gameplay.\n" +
                "Make sure you think carefully before choosing your answer, once you choose it, it's final.\n" +
                "Have fun, challenge yourself, and set new records!" +
                "\n\nAre you ready to start?");

        builder.setPositiveButton("Start Game", (dialog, which) -> startGame());

        builder.setNegativeButton("Just Browsing", (dialog, which) -> btnStartGame.setVisibility(View.VISIBLE));
        builder.setCancelable(false);
        builder.show();
    }

    private void startCountdown() {
        btnStartGame.setEnabled(false);
        final int[] countdown = {3};
        final Handler handler = new Handler();
        final Runnable countdownRunnable = new Runnable() {
            @SuppressLint("SetTextI18n")
            @Override
            public void run() {
                if (countdown[0] > 0) {
                    // 显示倒计时数字
                    tvQuestion.setText(String.valueOf(countdown[0]));
                    countdown[0]--;
                    handler.postDelayed(this, 1000);
                } else {
                    // 显示 "GO!" 然后开始游戏
                    tvQuestion.setText("GO!");
                    handler.postDelayed(() -> {
                        resetGame();
                        startTimer();
                        btnStartGame.setEnabled(true);
                    }, 1000);
                }
            }
        };
        handler.post(countdownRunnable);
    }

    private void generateNewQuestion() {
        for (Button btn : answerButtons) {
            btn.setEnabled(true);
        }
        tvProgress.setText(String.format(Locale.getDefault(), "%d/%d", questionCount, TOTAL_QUESTIONS));
        questionCount++;
        if (questionCount >= TOTAL_QUESTIONS + 1) {
            showResults();
        } else {
            Random random = new Random();
            int num1 = random.nextInt(100);
            int num2 = random.nextInt(100);
            int operator = random.nextInt(4); // 0 for add, 1 for subtract, 2 for multiply, 3 for divide

            switch (operator) {
                case 0:
                    currentQuestion = num1 + " + " + num2;
                    correctAnswer = (double) (num1 + num2);
                    break;
                case 1:
                    currentQuestion = num1 + " - " + num2;
                    correctAnswer = (double) (num1 - num2);
                    break;
                case 2:
                    currentQuestion = num1 + " * " + num2;
                    correctAnswer = (double) num1 * num2;
                    break;
                case 3:
                    currentQuestion = num1 + " / " + num2;
                    correctAnswer = num1 / (double) num2;
                    break;
            }

            correctAnswerText = String.format(Locale.getDefault(), "%.1f", correctAnswer);
            System.out.println(correctAnswerText);

            tvQuestion.setText(currentQuestion);
            tvResult.setText("");

            setAnswerOptions();
        }

    }

    private void setAnswerOptions() {
        List<Double> options = generateOptions();
        correctAnswerIndex = new Random().nextInt(4);
        for (int i = 0; i < answerButtons.length; i++) {
            String optionText = String.format(Locale.getDefault(), "%.1f", options.get(i));
            answerButtons[i].setText(optionText);
        }
    }

    private List<Double> generateOptions() {
        List<Double> options = new ArrayList<>();
        options.add(correctAnswer);

        Random random = new Random();
        while (options.size() < 4) {
            double fakeOption;

            if (currentQuestion.contains("+") || currentQuestion.contains("-")) {
                do {
                    fakeOption = (double) (random.nextInt(200) - 100);
                } while (fakeOption == correctAnswer);
            } else {

                do {
                    fakeOption = correctAnswer + (random.nextDouble() - 0.5);
                } while (fakeOption == correctAnswer);
            }

            options.add(fakeOption);
        }

        Collections.shuffle(options);
        return options;
    }



    @SuppressLint("SetTextI18n")
    private void checkAnswer(Button selectedButton) {
        for (Button btn : answerButtons) {
            btn.setEnabled(false);
        }
        String selectedAnswer = selectedButton.getText().toString();
        if (selectedAnswer.equals(correctAnswerText)) {
            int timeBonus = secondsElapsed <= 10 ? 5 : 0;
            updateScore(10 + timeBonus);
            tvResult.setText("Correct!");
            generateNewQuestion();
        } else {
            tvResult.setText("Wrong! Correct answer is " + correctAnswerText);
            btnConfirm.setVisibility(View.VISIBLE);
        }
    }

    private void showResults() {
        stopTimer();
        long totalTime = System.currentTimeMillis() - startTime;

        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Round Completed");

        String formattedTime = formatTime(totalTime);
        String message = String.format(Locale.getDefault(), "Your Score: %d\nTime Used: %s", score, formattedTime);
        builder.setMessage(message);

        saveScore(score, formattedTime);

        builder.setPositiveButton("OK", (dialog, which) -> showLeaderboard(true));
        builder.setCancelable(false);
        builder.show();
    }


    private void saveScore(int score, String formattedTime) {
        SharedPreferences prefs = getSharedPreferences("GameScores", MODE_PRIVATE);
        SharedPreferences.Editor editor = prefs.edit();
        int currentRound = prefs.getInt("roundsPlayed", 0);
        editor.putInt("scoreRound" + currentRound, score);
        editor.putString("timeRound" + currentRound, formattedTime);
        editor.putInt("roundsPlayed", currentRound + 1);
        editor.apply();
    }


    private void showLeaderboard(boolean flag) {
        SharedPreferences prefs = getSharedPreferences("GameScores", MODE_PRIVATE);
        int roundsPlayed = prefs.getInt("roundsPlayed", 0);

        StringBuilder leaderboard = new StringBuilder();
        for (int i = 0; i < roundsPlayed; i++) {
            int roundScore = prefs.getInt("scoreRound" + i, 0);
            String roundTime = prefs.getString("timeRound" + i, "00:00:00");
            leaderboard.append(String.format(Locale.getDefault(), "Round %d: Score: %d, Time: %s\n",
                    i + 1, roundScore, roundTime));
        }

        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Leaderboard");
        if (leaderboard.toString().equals("")) leaderboard.append("No records yet!");
        builder.setMessage(leaderboard.toString());
        builder.setPositiveButton("OK", (dialog, which) -> {
            if (flag) {
                resetGame();
            }
        });
        builder.setNegativeButton("Clear Leaderboard", (dialog, which) -> clearLeaderboard());
        builder.setCancelable(false);
        builder.show();
    }

    private void clearLeaderboard() {

        SharedPreferences prefs = getSharedPreferences("GameScores", MODE_PRIVATE);
        SharedPreferences.Editor editor = prefs.edit();
        editor.clear();
        editor.apply();

        Toast.makeText(this, "Leaderboard cleared", Toast.LENGTH_SHORT).show();
    }


    private void resetGame() {
        score = 0;
        questionCount = 0;
        updateScore(0);
        generateNewQuestion();
        resetTimer();
        for (Button btn : answerButtons) {
            btn.setEnabled(true);
        }
        btnConfirm.setVisibility(View.GONE);
    }

    private void resetTimer() {
        timerHandler.removeCallbacks(timerRunnable);
        startTime = System.currentTimeMillis(); // 重置开始时间
        timerHandler.postDelayed(timerRunnable, 10); // 重新启动计时器
    }


    @SuppressLint("SetTextI18n")
    private void updateScore(int points) {
        score += points;
        tvScore.setText("Score: " + score);
    }

    private void startTimer() {
        startTime = System.currentTimeMillis();
        timerHandler.post(timerRunnable);
    }

    private void stopTimer() {
        timerHandler.removeCallbacks(timerRunnable);
    }

    private String formatTime(long millis) {
        int hours = (int) (millis / 3600000);
        int minutes = (int) (millis % 3600000) / 60000;
        int seconds = (int) (millis % 60000) / 1000;
        return String.format(Locale.getDefault(), "%02d:%02d:%02d", hours, minutes, seconds);
    }


    @Override
    protected void onPause() {
        super.onPause();
//        timerHandler.removeCallbacks(timerRunnable);
    }

    @Override
    protected void onResume() {
        super.onResume();
//        resetGame();
    }
}
